
#include <stddef.h>
#include <Utility.h>
#include <Log.h>
#include <BSP/BSP_Uart_2.h>
#include "IO.h"

#include "FreeRTOS.h"
#include "stream_buffer.h"
#include "timers.h"

static StreamBufferHandle_t ble_rx_stream_buffer;
static TimerHandle_t ble_rts_timer;
static const IO_T ble_rts = IO_INIT_TABLE(GPIOC, GPIO_PIN_14);
static const IO_T ble_cts = IO_INIT_TABLE(GPIOA, GPIO_PIN_5);

static void BLE_IF_RxCallback(uint16_t rx){
	if(!ble_rx_stream_buffer){
		return ;
	}
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
	uint8_t rd = rx;
	xStreamBufferSendFromISR(ble_rx_stream_buffer, &rd, 1, &xHigherPriorityTaskWoken);
	portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

static void ble_rts_timer_cb( TimerHandle_t xTimer ){
	IO_Set(&ble_rts, 1);
}

void BLE_IF_Init(void){
	ble_rx_stream_buffer = xStreamBufferCreate(1024, 1);
	if(!ble_rx_stream_buffer){
		LOGE(NULL, "no memory!");
		return ;
	}
	ble_rts_timer = xTimerCreate("rts", 1000, pdFALSE, NULL, ble_rts_timer_cb);
	IO_Init(&ble_rts, IO_Mode_OUT);
	IO_Set(&ble_rts, 1);
	IO_Init(&ble_cts, IO_Mode_IPU);
	
	BSP_Uart_Init(1);
	BSP_Uart_SetRxCallback(1, BLE_IF_RxCallback);
}

int BLE_IF_Receive(uint8_t* buffer, uint32_t length, uint32_t wtime){
	int len = xStreamBufferReceive(ble_rx_stream_buffer, buffer, length, wtime);
	
	return len;
}

void BLE_IF_Send(const uint8_t *buffer, uint32_t length){
	uint32_t i;
	
	for(i = 0; i < length; i++){
		BSP_Uart_Send(1, buffer[i]);
	}
}

void BLE_IF_Clear(void){
	xStreamBufferReset(ble_rx_stream_buffer);
}

void BLE_IF_SetRTS(uint8_t state){
	IO_Set(&ble_rts, state);
}

int BLE_IF_GetCTS(void){
	return IO_Get(&ble_cts);
}

void BLE_IF_TriggerRTS(void){
	if(ble_rts_timer){
		IO_Set(&ble_rts, 0);
		xTimerReset(ble_rts_timer, 500);
	}
}


